	/*
 * CommunicationVendedor.h
 *
 */

#ifndef COMMUNICATIONVENDEDOR_H_
#define COMMUNICATIONVENDEDOR_H_

#include <list>
#include "MiddlewareCommon.h"
#include "../IPC/MessageQueue.h"
#include "../IPC/Sequence.h"


namespace middleware {

class CommunicationVendedor
{
public:
	typedef enum{REQUEST_VENDEDOR_ID=0, ITEM_ORDEN_COMPRA,FIN_ORDEN_COMPRA}VendedorMessageType;
	static const int FINALIZACION_ORDEN_COMPRA= -1;

public:
	typedef enum{CLIENTE=0,VENDEDOR, UNDEFINED_TYPE}VendedorCommunicationType;
	typedef enum{OC_OK=0, OC_ERROR_NO_HAY_ESPACIO}OrdenCompraStatus;

public:

	//For data alignment purposes (32/64 bit compatibility)
	#pragma pack(push, 1)
	struct VendedorRequestStruct
	{
		VendedorMessageType requestType;
		ProductoCantidad producto;
		OrdenCompraHeader ordenCompra;
	};

	struct VendedorReplyStruct
	{
		int vendedorId;
		OrdenCompraStatus status;
	};

	struct AvailableVendedorStruct
	{
		int clientId;
		int vendedorId;
	};
	#pragma pack(pop)

typedef ipc::MessageQueue<AvailableVendedorStruct> AvailableVendedorQueue;
typedef ipc::MessageQueue<VendedorRequestStruct> VendedorRequestQueue;
typedef ipc::MessageQueue<VendedorReplyStruct> VendedorReplyQueue;

public:
	CommunicationVendedor(std::string hostName);
	virtual ~CommunicationVendedor();


	//Metodos Vendedor id
	int generateVendedorId();

	void avisarVendedorDisponible(int vendedorId);

	int getVendedorId(const int clientId);

	//Orden de compra
	//TODO pq devolvia int/bool?
	int sendOrdenCompra(OrdenCompra &ordenCompra);

	void receiveOrdenCompra(int vendedorId,int &clientId,
			 	 	 	 	 ProductoCantidad &producto,
			 	 	 	 	 OrdenCompraHeader &ordenCompra,
			 	 	 	 	 bool &ordenCompraEnded);

	void respondOrdenCompra(int clientId,OrdenCompraStatus status);

	int generateOrdenCompraId();

	//Creacion
	static void create(VendedorCommunicationType type,std::string hostName);

	static void launchForClient(std::string hostName, int clientId);

	static void destroy(VendedorCommunicationType type,std::string hostName);

public:
	static const std::string REQUEST_QUEUE_PATH;
	static const std::string REPLY_QUEUE_PATH;
	static const std::string AVAILABLE_QUEUE_PATH;
	static const std::string VENDEDORID_SEQUENCE_PATH;
	static const std::string OC_ID_SEQUENCE_PATH;

	static const char REQUEST_QUEUE_KEY_CLI_SIDE = 'a';
	static const char REPLY_QUEUE_KEY_CLI_SIDE = 'b';
	static const char AVAILABLE_QUEUE_KEY_CLI_SIDE = 'c';

	static const char REQUEST_QUEUE_KEY_VEND_SIDE = 'd';
	static const char REPLY_QUEUE_KEY_VEND_SIDE = 'e';
	static const char AVAILABLE_QUEUE_KEY_VEND_SIDE = 'f';

	static const char VENDEDORID_SEQUENCE_KEY = 'g';
	static const char OC_ID_SEQUENCE_KEY = 'h';

//TODO fix, solop para pruebas
public:

	ipc::MessageQueue<VendedorRequestStruct> m_RequestQueue;
	ipc::MessageQueue<VendedorReplyStruct> m_ReplyQueue;
	AvailableVendedorQueue m_AvailableVendedor;
	ipc::Sequence m_ordenCompraIdGenerator;

	int m_mTypeVendedor;
	int m_mTypePedidoVendedorLibre;
	int m_mTypeInformarVendedorLibre;
	std::string m_HostName;

	static const Uid UIDVendedorRequest,
	UIDVendedorReply,
	UIDVendedorAvailable,
	UIDVendedorIdGenerator,
	UIDOcGenerator;
};

} /* namespace middleware */
#endif /* COMMUNICATIONVENDEDOR_H_ */
